const gulp = require('gulp');
const htmlImport = require('gulp-html-import');  //html引入
const htmlmin = require('gulp-htmlmin');         //压缩html
const autoprefixer = require('gulp-autoprefixer'); //css游览器兼容
const cleanCSS = require('gulp-clean-css');      // 压缩css
const sass = require('gulp-sass');               // 编译scss 为 css
const uglify = require('gulp-uglify');           // 压缩js
const jshint = require("gulp-jshint");           // js检查
const babel = require('gulp-babel');             // ES6转ES5
const imagemin = require('gulp-imagemin');       // 压缩图片
const cached = require("gulp-cached");           // 只传入改动的资源
const rename = require('gulp-rename');           // 替换路径
const rev = require('gulp-rev-dxb')              //生成映射路径
const revCollector = require('gulp-rev-collector-dxb') //替换版本号路径插件
const del = require("del");                      //每次构建gulp之前，清除目标文件dist
const connect = require('gulp-connect');         //引入gulp-connect模块 浏览器刷新
const open = require('open');                    //自动打开网页

// 统筹路径
var srcs = {
    "assets": ["./public/assets/*.*", "./public/assets/**/*.*"],                        //两端公用资源 

    "pc_module": ["./public/pc/components/"],                                           //pc端公共组件
    "pc_html": ["./public/pc/*.html"],                                                  //pc端页面
    "pc_assets": ["./public/pc/assets/*.*", "./public/pc/assets/**/*.*"],               //pc端公用资源
    "pc_revjs": ["./public/pc/src/js/*.*", "./public/pc/src/js/**/*.*"],                //pc端可输出js
    "pc_revcss": ["./public/pc/src/css/*.*", "./public/pc/src/css/**/*.*"],             //pc端可输出css
    "pc_revimg": ["./public/pc/src/images/*.*", "./public/pc/src/images/**/*.*"],       //pc端可输出css

    "mobile_module": ["./public/mobile/components/"],                                                 //mobile端公共组件
    "mobile_html": ["./public/mobile/*.html"],                                                        //mobile端页面
    "mobile_assets": ["./public/mobile/assets/*.*", "./public/mobile/assets/**/*.*"],                 //mobile端公用资源
    "mobile_revjs": ["./public/mobile/src/js/*.*", "./public/mobile/src/js/**/*.*"],                  //mobile端可输出js
    "mobile_revcss": ["./public/mobile/src/css/*.*", "./public/mobile/src/css/**/*.*"],               //mobile端可输出css
}

// https://github.com/kangax/html-minifier#user-content-options-quick-reference
// html-minifier 配置
var options = {
    collapseWhitespace: true, //压缩HTML
    collapseBooleanAttributes: true, //省略布尔属性的值 <input checked="true"/> ==> <input />
    removeComments: true, //清除HTML注释
    removeEmptyAttributes: true, //删除所有空格作属性值 <input id="" /> ==> <input />
    removeScriptTypeAttributes: true, //删除<script>的type="text/javascript"
    removeStyleLinkTypeAttributes: true, //删除<style>和<link>的type="text/css"
    minifyJS: true, //压缩js
    minifyCSS: true //压缩css
};



//PC
// 分发组件，压缩html
gulp.task('pc_html', () => {
    return gulp.src(srcs.pc_html)
        .pipe(cached(srcs.pc_html))
        .pipe(htmlImport(srcs.pc_module))
        .pipe(rename({
            dirname: ''
        }))
        .pipe(htmlmin(options))
        .pipe(gulp.dest('dist/pc/page'))
        .pipe(connect.reload());
});
//处理pc端公用文件
gulp.task('pc_assets', function () {
    return gulp.src(srcs.pc_assets)
        .pipe(cached('pc_assets'))
        .pipe(gulp.dest('dist/pc/assets'))
});
//处理pc端js进行编译，混淆，hash增加
gulp.task('pc_revjs', function () {
    return gulp.src(srcs.pc_revjs)
        .pipe(cached('pc_revjs'))
        .pipe(jshint()) //检查代码
        .pipe(babel({
            presets: ['@babel/env']
        }))
        .pipe(uglify())
        .pipe(rev()) //js文件生成版本号,
        .pipe(gulp.dest('dist/pc/src/js')) //将js文件输出到dist/js目录下
        .pipe(rev.manifest({
            path: "../../JS.json",
            merge: true
        })) //并将所有带有版本号的文件放入json中
        .pipe(gulp.dest('dist/pc/src/js'))
        .pipe(connect.reload());
});
//处理pc端css进行编译，混淆，hash增加
gulp.task('pc_revcss', function () {
    return gulp.src(srcs.pc_revcss)
        .pipe(cached('pc_revcss'))
        .pipe(sass())
        .pipe(autoprefixer({
            overrideBrowserslist: [
                "Android 4.1",
                "iOS 7.1",
                "Chrome > 31",
                "ff > 31",
                "ie >= 8"
            ],
            grid: true
        }))
        // 2. 压缩文件
        .pipe(cleanCSS())
        .pipe(rev()) //将所有匹配到的文件名全部生成相应的版本号
        .pipe(gulp.dest('dist/pc/src/css')) //将css文件输出到dist目录
        .pipe(rev.manifest({
            path: "../../CSS.json",
            merge: true
        })) //并将所有带有版本号的文件放入json中
        // 3. 另存压缩后的文件
        .pipe(gulp.dest('dist/pc/src/css'))
        .pipe(connect.reload());
});
// 图片异步处理
gulp.task('pc_revimg', async function () {
    gulp.src(srcs.pc_revimg)
        .pipe(cached('pc_revimg'))
        // .pipe(await imagemin())    //压缩图片，建议使用熊猫压缩提前压缩
        .pipe(gulp.dest('dist/pc/src/images'))
});
//hash替换
gulp.task('pc_rev', function () {
    return gulp.src(['dist/pc/*.json', 'dist/pc/page/*.html'])
        .pipe(revCollector({
            replaceReved: true, //允许替换, 已经被替换过的文件
            dirReplacements: {
                'css': 'css',
                'js': 'js',
                'json': 'json'
            }
        }))
        .pipe(gulp.dest('dist/pc'))
});
// 替换文件
gulp.task('clean:pc', function () {
    return del(['dist/pc/**'])
});

// 监听
gulp.task('watchs:pc', function () { //监听变化执行任务
    //当匹配任务变化才执行相应任务
    gulp.watch(srcs.assets, gulp.series('assets', 'pc_rev'));
    gulp.watch(srcs.pc_module, gulp.series('pc_html', 'pc_rev'));
    gulp.watch(srcs.pc_html, gulp.series('pc_html', 'pc_rev'));
    gulp.watch(srcs.pc_revjs, gulp.series('pc_revjs'));
    gulp.watch(srcs.pc_revcss, gulp.series('pc_revcss'));
    gulp.watch(srcs.pc_revimg, gulp.series('pc_revimg'));
    gulp.watch(srcs.pc_assets, gulp.series('pc_assets', 'pc_rev'));
    connect.server({
        root: 'dist', //根目录
        port: 9898,
        name: "已启动PC端服务",
        livereload: true, //自动更新
    });
    open('http://localhost:9898/pc/index.html');
})



//mobile
// 分发组件，压缩html
gulp.task('mobile_html', () => {
    return gulp.src(srcs.mobile_html)
        .pipe(cached(srcs.mobile_html))
        .pipe(htmlImport(srcs.mobile_module))
        .pipe(rename({
            dirname: ''
        }))
        .pipe(htmlmin(options))
        .pipe(gulp.dest('dist/mobile/page'))
        .pipe(connect.reload());
});
//处理mobile端公用文件
gulp.task('mobile_assets', function () {
    return gulp.src(srcs.mobile_assets)
        .pipe(cached('mobile_assets'))
        .pipe(gulp.dest('dist/mobile/assets'))
});
//处理mobile端js进行编译，混淆，hash增加
gulp.task('mobile_revjs', function () {
    return gulp.src(srcs.mobile_revjs)
        .pipe(cached('mobile_revjs'))
        .pipe(jshint()) //检查代码
        .pipe(babel({
            presets: ['@babel/env']
        }))
        .pipe(uglify())
        .pipe(rev()) //js文件生成版本号,
        .pipe(gulp.dest('dist/mobile/src/js')) //将js文件输出到dist/js目录下
        .pipe(rev.manifest({
            path: "../../JS.json",
            merge: true
        })) //并将所有带有版本号的文件放入json中
        .pipe(gulp.dest('dist/mobile/src/js'))
        .pipe(connect.reload());
});
//处理mobile端css进行编译，混淆，hash增加
gulp.task('mobile_revcss', function () {
    return gulp.src(srcs.mobile_revcss)
        .pipe(cached('mobile_revcss'))
        .pipe(sass())
        .pipe(autoprefixer({
            overrideBrowserslist: [
                "Android 4.1",
                "iOS 7.1",
                "Chrome > 31",
                "ff > 31",
                "ie >= 8"
            ],
            grid: true
        }))
        // 2. 压缩文件
        .pipe(cleanCSS())
        .pipe(rev()) //将所有匹配到的文件名全部生成相应的版本号
        .pipe(gulp.dest('dist/mobile/src/css')) //将css文件输出到dist目录
        .pipe(rev.manifest({
            path: "../../CSS.json",
            merge: true
        })) //并将所有带有版本号的文件放入json中
        // 3. 另存压缩后的文件
        .pipe(gulp.dest('dist/mobile/src/css'))
        .pipe(connect.reload());
});
// 图片异步处理
gulp.task('mobile_revimg', async function () {
    gulp.src(srcs.mobile_revimg)
        .pipe(cached('mobile_revimg'))
        // .pipe(await imagemin())    //压缩图片，建议使用熊猫压缩提前压缩
        .pipe(gulp.dest('dist/mobile/src/images'))
});
//hash替换
gulp.task('mobile_rev', function () {
    return gulp.src(['dist/mobile/*.json', 'dist/mobile/page/*.html'])
        .pipe(revCollector({
            replaceReved: true, //允许替换, 已经被替换过的文件
            dirReplacements: {
                'css': 'css',
                'js': 'js',
                'json': 'json'
            }
        }))
        .pipe(gulp.dest('dist/mobile'))
});
// 替换文件
gulp.task('clean:mobile', function () {
    return del(['dist/mobile/**'])
});

// 监听
gulp.task('watchs:mobile', function () { //监听变化执行任务
    //当匹配任务变化才执行相应任务
    gulp.watch(srcs.assets, gulp.series('assets', 'mobile_rev'));
    gulp.watch(srcs.mobile_module, gulp.series('mobile_html', 'mobile_rev'));
    gulp.watch(srcs.mobile_html, gulp.series('mobile_html', 'mobile_rev'));
    gulp.watch(srcs.mobile_revjs, gulp.series('mobile_revjs'));
    gulp.watch(srcs.mobile_revcss, gulp.series('mobile_revcss'));
    gulp.watch(srcs.mobile_revimg, gulp.series('mobile_revimg'));
    gulp.watch(srcs.mobile_assets, gulp.series('mobile_assets','mobile_rev'));
    connect.server({
        root: 'dist', //根目录
        port: 9898,
        name: "已启动mobile端服务",
        livereload: true, //自动更新
    });
    open('http://localhost:9898/mobile/index.html');
})


// 两端公用
//处理两端公用文件
gulp.task('assets', function () {
    return gulp.src(srcs.assets)
        .pipe(cached('assets'))
        .pipe(gulp.dest('dist/assets'))
});

// 产出dist
gulp.task('clean:dist', function () {
    return del(['dist/**'])
});

// 监听
gulp.task('watchs', function () { //监听变化执行任务
    //当匹配任务变化才执行相应任务
    gulp.watch(srcs.assets, gulp.series('assets', 'pc_rev', 'mobile_rev'));
    gulp.watch(srcs.pc_module, gulp.series('pc_html', 'pc_rev'));
    gulp.watch(srcs.pc_html, gulp.series('pc_html', 'pc_rev'));
    gulp.watch(srcs.pc_revjs, gulp.series('pc_revjs'));
    gulp.watch(srcs.pc_revcss, gulp.series('pc_revcss'));
    gulp.watch(srcs.pc_revimg, gulp.series('pc_revimg'));
    gulp.watch(srcs.pc_assets, gulp.series('pc_assets', 'pc_rev'));
    gulp.watch(srcs.mobile_module, gulp.series('mobile_html', 'mobile_rev'));
    gulp.watch(srcs.mobile_html, gulp.series('mobile_html', 'mobile_rev'));
    gulp.watch(srcs.mobile_revjs, gulp.series('mobile_revjs'));
    gulp.watch(srcs.mobile_revcss, gulp.series('mobile_revcss'));
    gulp.watch(srcs.mobile_revimg, gulp.series('mobile_revimg'));
    gulp.watch(srcs.mobile_assets, gulp.series('mobile_assets','mobile_rev'));
    connect.server({
        root: 'dist', //根目录
        port: 9898,
        livereload: true, //自动更新
    });
    open('http://localhost:9898/pc/index.html');
})




// pc任务进程处理
gulp.task('pc_init', gulp.series('clean:pc', gulp.parallel('assets', 'pc_html', 'pc_assets', 'pc_revjs', 'pc_revcss', 'pc_revimg')));
gulp.task('pc_build', gulp.series("clean:pc",
    gulp.series('pc_init',
        gulp.parallel('pc_rev')
    )
));
gulp.task('pc_serve', gulp.series('pc_build', 'watchs:pc'));



// mobile任务进程处理
gulp.task('mobile_init', gulp.series('clean:mobile', gulp.parallel('assets', 'mobile_html', 'mobile_assets', 'mobile_revjs', 'mobile_revcss', 'mobile_revimg')));
gulp.task('mobile_build', gulp.series("clean:mobile",
    gulp.series('mobile_init',
        gulp.parallel('mobile_rev')
    )
));
gulp.task('mobile_serve', gulp.series('mobile_build', 'watchs:mobile'));



gulp.task('serve', gulp.series("clean:dist", gulp.series('pc_build', 'mobile_build', 'watchs')));